package com.verlet.springbootdemo.util;

/**
 * 常用于同一调用链路，需要保存一个共享值
 *
 * @author verlet
 * @date 2021-07-20 22:14
 */
public class ThreadLocalUtil {

    private ThreadLocalUtil() {
        throw new IllegalStateException("Utility class");
    }

    private static final ThreadLocal<Object> THREAD_LOCAL = new ThreadLocal<>();

    public static <T> void setThreadLocalValue(T t) {
        THREAD_LOCAL.set(t);
    }

    @SuppressWarnings("unchecked")
    public static <T> T getThreadLocalValue() {
        Object o = THREAD_LOCAL.get();
        if (o == null) {
            return null;
        }
        return (T) o;
    }

    /**
     * 使用完一定要remove，减少内存泄漏问题
     */
    public static void removeThreadLocal() {
        THREAD_LOCAL.remove();
    }

    /**
     * 子线程可以获取父线程的本地变量
     */
    private static final InheritableThreadLocal<Object> INHERITABLE_THREAD_LOCAL = new InheritableThreadLocal<>();

    public static <T> void setInheritableThreadLocalValue(T t) {
        INHERITABLE_THREAD_LOCAL.set(t);
    }

    /**
     * 当子线程创建时会复制父线程inheritableThreadLocals <br/>
     * 当父线程发生改变时候，次子线程不会改变，不会重新复制父线程inheritableThreadLocals
     *
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T getInheritableThreadLocalValue() {
        Object o = INHERITABLE_THREAD_LOCAL.get();
        if (o == null) {
            return null;
        }
        return (T) o;
    }

    public static void removeInheritableThreadLocal() {
        INHERITABLE_THREAD_LOCAL.remove();
    }
}
